﻿/******************************************************************************
* File description: animationParseHEX.cpp
* Function: 解析下位机指令，并分发给动画Manager
* Current Version: 1.0.0
* Author: JNN
* Date: 2025-07-01
*  -----
*  Copyright by 博坤生物 .
 *****************************************************************************/


#include "animationParseHEX.h"


/** @brief 构造函数 */
AnimationParseHEX::AnimationParseHEX()
{

}

/** @brief 单例函数 */
AnimationParseHEX& AnimationParseHEX::I(){
    static AnimationParseHEX instance;
    return instance;
}

/** @brief 外部初始化动画的state指针 */
void AnimationParseHEX::initState(AnimationState_Shifting *state_shifting, AnimationState_Practice *state_practice, AnimationState_Purify *state_purify){
    __LOG_FSTART__;
    _state_shifting = state_shifting;
    _state_practice = state_practice;
    _state_purify = state_purify;
    __LOG_FEND__;
}

// 62 00 00 3A 00 08 01 00 01 01 00 64 B7 9A AA 55
// 62 00 00 3A 00 06 01 01 02 01 B7 9A AA 55
// 62 00 00 3A 00 06 01 02 01 01 B7 9A AA 55


/** @brief 解析错误指令 */
bool AnimationParseHEX::parseErrorMsg(QStringList instruct){

    for(int i = 0; i < instruct.size(); i ++){
        if(instruct[i] == "0B" || instruct[i] == "14"){     // 1号注射器

        }else if(instruct[i] == "0C" || instruct[i] == "15"){     // 2号注射器

        }else if(instruct[i] == "0D" || instruct[i] == "16"){     // 3号注射器

        }else if(instruct[i] == "0E" || instruct[i] == "17"){     // 4号注射器

        }else if(instruct[i] == "0F" || instruct[i] == "18"){     // 5号注射器

        }else if(instruct[i] == "10" || instruct[i] == "19"){     // 6号注射器

        }else if(instruct[i] == "11" || instruct[i] == "20"){     // 7号注射器

        }else if(instruct[i] == "12"){                            // 传靶气路压力异常

        }
    }

    return true;
}

/** @brief 解析传入指令
 *  @param type 0上位机发的指令  1设备发的指令
 *  @return 解析是否成功  */
bool AnimationParseHEX::parse(QStringList instruct, int type){


    if(!_state_purify || !_state_practice || !_state_shifting){
        __LOG_ERROR("state=nullptr");
        qDebug() << "[错误] 动画解析失败：state状态未建立";
        return false;
    }

    if(instruct.size() < 8){
        __LOG_ERROR("InstructLengthError: " + instruct.join(" "));
        qDebug() << "[错误] 指令太短了";
        return false;
    }



    if(instruct[3]== "3D" && instruct[6] == "03"){      // 纯化电机速度指令
        parsingMotor(instruct);
        return true;
    }


    qDebug() << "接收到设备指令，开始执行解析" << instruct;
    __LOG0(instruct.join(" "), "AnimInstruct");



    if(type == 1){          // 设备指令，用于完成时关闭
        if(_historyInstruct.contains(instruct[6])){
//            if(_historyInstruct[instruct[6]] == "23"){      // 水泵     // 水泵的关闭删掉了
//                _state_practice->setPump1State(0);
//                _state_practice->setPumpN2State(0);
//            }
            if(_historyInstruct[instruct[6]] == "24"){      // 气泵
                _state_practice->setPump2State(0);
            }
            if(_historyInstruct[instruct[6]] == "21"){      // 放靶->打靶
                _state_shifting->setBlowTargetState(0);
            }
            if(_historyInstruct[instruct[6]] == "28"){      // 打靶->放靶
                _state_practice->setBlowTargetState(0);
            }
            if(_historyInstruct[instruct[6]] == "2E"){      // 加热
                _state_purify->changeHeating(false);
            }
            if(_historyInstruct[instruct[6]] == "05"){      // 纯化往废液瓶里面打的蠕动泵
                _state_purify->changePPumpState(0);
            }
            if(_historyInstruct[instruct[6]] == "2C"){
                _state_shifting->setPPumpState(0);
            }
        }
        return true;
    }

    if(_lastInstruction == instruct.join(" ")){
        __LOG_INFO("指令发送重复，跳过解析");
        return false;
    }

    _lastInstruction = instruct.join(" ");

    _historyInstruct[instruct[6]] = instruct[7];

    if(instruct[7] == "01"){    // 注射器
        parsingSyringe(instruct);
    }else if(instruct[7] == "02"){    // 阀门
        parsingValve(instruct);
    }else if(instruct[7] == "03"){    // 转盘
        parsingWheel(instruct);
    }else if(instruct[7] == "04"){    // 推盖
        parsingHatPush(instruct);
        QTimer::singleShot(1500, [this, instruct](){     // 推盖和盖盖指令在这块合并了
            parsingHatPress(instruct);
        });
    }else if(instruct[7] == "05"){
        parsingPeristalticPump_Purify(instruct);     // 5 纯化往废液瓶打的蠕动泵
    }

    else if(instruct[7] == "20"){      // 20 挡板
        parsingBaffle(instruct);
    }else if(instruct[7] == "21"){      // 21 放靶往打靶吹的气泵
        parsingPushPump_Shifting(instruct);
    }else if(instruct[7] == "22"){      // 22 吸靶

    }else if(instruct[7] == "23"){      // 23 水泵
        parsingWaterPump(instruct);
    }else if(instruct[7] == "24"){      // 24 气泵
        parsingAirPump(instruct);
    }else if(instruct[7] == "25"){      // 25 加速模块移靶和送靶
        parsingMoveTarget_Practice(instruct);
    }else if(instruct[7] == "26"){      // 26 抱闸
        parsingBrake(instruct);
    }else if(instruct[7] == "27"){      // 27 进料口
        parsingMoveFeedPort_Practice(instruct);
    }else if(instruct[7] == "28"){      // 28 加速吹走瓶子
        parsingPushPump_Practice(instruct);
    }else if(instruct[7] == "29"){      // 29 转靶-盖盖-这里负责啥我也不知道
        parsingOpCap_Mov(instruct);
    }else if(instruct[7] == "30"){      // 30 转靶-盖盖-这里负责夹紧
        parsingOpCap_Clamp(instruct);
    }else if(instruct[7] == "2A"){      // 2A 转靶-取靶
        parsingOpTarget_Practice(instruct);
    }else if(instruct[7] == "2B"){      // 2B 夹爪
        parsingClamp(instruct);
    }else if(instruct[7] == "2C"){      // 2C 转靶家的蠕动泵
        parsingPeristalticPump_Shifting(instruct);
    }else if(instruct[7] == "2E"){
        parsingHeating(instruct);
    }


    return true;
}


/** @brief 已弃用 */
bool AnimationParseHEX::startParsing(QStringList instruct){

    if(instruct[0] == "推盖"){
        parsingHatPush(instruct);
        return true;
    }if(instruct[0] == "盖盖"){
        parsingHatPress(instruct);
        return true;
    }
    if(instruct.size() < 8){
        qDebug() << "ERROR: [Class]AnimationParseHEX [Func]startParsing - instruct out-of-range" << instruct.size();
        return false;
    }

    if(instruct[3]== "3D" && instruct[6] == "03"){      // 电机指令
        parsingMotor(instruct);
        return true;
    }

    qDebug() << "接收到设备解析指令，开始执行解析" << instruct;
    __LOG_INFO("接收到设备解析指令，开始执行解析:" + instruct.join(" "));

//    if(instruct[7] == "05"){
//        parsingHat(_state_purify, instruct);
//    }

    return true;
}



/** @brief 解析注射器指令 */
bool AnimationParseHEX::parsingSyringe(QStringList instruct){

    __LOG_FSTART(instruct);

    if(instruct.size() < 15){
        qDebug() << "ERROR: [Class]AnimationParseHEX [Func]startParsing - instruct out-of-range" << instruct.size();
        __LOG_FEND(false);
        return false;
    }

    // 08-编号 09-动作01打液02吸液 10 11-步数/s 12 13 14 15-总步数

    int idx = instruct[8].toInt();

    int direct = instruct[9].toInt()*2-3;               // 方向

    double stepSpeed = CommonHelper::Common().SixteenToTen(instruct[10]+instruct[11]).toInt();
    double stepNum = CommonHelper::Common().SixteenToTen(instruct[12]+instruct[13]+instruct[14]+instruct[15]).toInt();

    qDebug() << "接收注射器指令" << "[编号]" << idx << "[方向]" << direct << "[速度]" << stepSpeed << "总步数" << stepNum;

    SyringeCalculator::refreshSyringeParams();

    double mmSpeed = SyringeCalculator::calStep2MM(idx, stepSpeed);
    double pushHeight = SyringeCalculator::calStep2MM(idx, stepNum);
    double syringeHeight = SyringeCalculator::getSyringeHeightMM(idx);

    qDebug() << "注射器速度" << mmSpeed << "  推的高度" << pushHeight << "  注射器的高度" << syringeHeight;

    _state_purify->changeSyringeSpeedTarget(idx, mmSpeed);      // [1] 变更标签上的速度

    if(syringeHeight == 0){
        __LOG_ERROR("division0Error");
        return false;
    }

    qDebug() << "速度百分比" << mmSpeed / syringeHeight;
    _state_purify->changeSyringe_dp(idx, -direct*(pushHeight / syringeHeight), mmSpeed / syringeHeight);        // [2] 变更注射器变化

    double diameter = SyringeCalculator::getSyringeDiameterMM(idx);
    double speed_ml_s = 3.14159 * (diameter*diameter) * mmSpeed / 4000;  // 毫升每秒

    qDebug() << "溶液的流速" << speed_ml_s << "ml/s";

    _state_purify->_pipeGraph->changeSyringeSpeed(idx, speed_ml_s);     // [3] 变更管道流速


    double pushVolumn = pow(diameter/2, 2) * pushHeight;        // 推的体积（单位可能有点问题，但是不管了……）

    // 单独处理一下溶靶瓶…………
    if(_state_purify->_valveState.size() > 3){


        if(SyringeCalculator::getSyringeHeightMM(0) == 0 || SyringeCalculator::getSyringeDiameterMM(0) == 0){
            __LOG_ERROR("division0Error");
            return false;
        }

        double bottleHeight = SyringeCalculator::getSyringeHeightMM(0);
        double bottlePushHeight = pushVolumn / pow(SyringeCalculator::getSyringeDiameterMM(0)/2, 2);
        double bottlePushPercent = bottlePushHeight / bottleHeight;
        double bottleMMSpeed = mmSpeed * (diameter*diameter) / pow(SyringeCalculator::getSyringeDiameterMM(0), 2);
        double bottlePercentSpeed = bottleMMSpeed / bottleHeight;
        if(idx == 1){
            if(_state_purify->_valveState[0] && _state_purify->_valveState[2]){
                _state_purify->changeSyringe_dp(0, direct*bottlePushPercent, bottlePercentSpeed);
            }
        }else if(idx == 2){
            if(_state_purify->_valveState[1] && _state_purify->_valveState[2]){
                _state_purify->changeSyringe_dp(0, direct*bottlePushPercent, bottlePercentSpeed);
            }
        }else if(idx == 3){
            if(_state_purify->_valveState[3]){
                _state_purify->changeSyringe_dp(0, direct*bottlePushPercent, bottlePercentSpeed);
            }
        }
    }
    __LOG_FEND(true);
    return true;
}

/** @brief 解析阀门指令 */
bool AnimationParseHEX::parsingValve(QStringList instruct){

    __LOG_FSTART(instruct);

    if(instruct.size() < 11){
        qDebug() << "ERROR: [Class]AnimationParseHEX [Func]startParsing - instruct out-of-range" << instruct.size();
        __LOG_FEND(false);
        return false;
    }
    QString valveState = CommonHelper::Common().SixteenToTwo(instruct[8]+instruct[9]+instruct[10]);
    // 补位
    int tsize = 24-valveState.size();
    for(int i = 0; i < tsize; i ++){
        valveState = "0"+valveState;
    }


    for(int i = 0; i < valveState.size(); i ++){

        int idx = i/8*8 + (7-i%8);

        int istate = QString(valveState[i]).toInt();
        qDebug() << "解析阀门" << idx;
        if(istate == 0){
            _state_purify->changeValve(idx, true);
        }else if(istate == 1){
            _state_purify->changeValve(idx, false);
        }
    }
//    _state_purify->changeValve(idx, status==1);
    __LOG_FEND(true);
    return true;
}

/** @brief 解析打靶-传靶气泵指令 */
bool AnimationParseHEX::parsingPushPump_Practice(QStringList instruct){
    if(instruct.size() < 10){
        return false;
    }
//    if(instruct[8].toInt() == 1){
//        _state_practice->setBlowTargetState(0);
//    }else if(instruct[8].toInt() == 0){
        _state_practice->setBlowTargetState(1);
//    }
    return true;
}

/** @brief 解析转靶-传靶气泵指令 */
bool AnimationParseHEX::parsingPushPump_Shifting(QStringList instruct){
    if(instruct.size() < 10){
        return false;
    }
//    if(instruct[8].toInt() == 1){
//        _state_shifting->setBlowTargetState(0);
//    }else if(instruct[8].toInt() == 0){
        _state_shifting->setBlowTargetState(1);
//    }
    return true;
}

/** @brief 解析纯化-转盘指令 */
bool AnimationParseHEX::parsingWheel(QStringList instruct){

    if(instruct.size() < 10){
        qDebug() << "ERROR: [Class]AnimationParseHEX [Func]startParsing - instruct out-of-range" << instruct.size();
        return false;
    }

    // 08-转动位置 09-盖盖(0不盖 1盖)
    int posi = instruct[8].toInt() -  1;        // 我这边的序号是0~8
    qDebug() << "解析转盘转动位置" << posi;
//    int addHat = instruct[9].toInt();
    _state_purify->turnWheel_posi(posi, 1);
//    if(addHat == 1){
//        QTimer::singleShot(1000, [_state_purify]{
//            _state_purify->addHat();
//        });
//    }
    return true;
}

/** @brief 解析纯化-推盖指令 */
bool AnimationParseHEX::parsingHatPush(QStringList instruct){
    _state_purify->pushHat();
    return true;
}
/** @brief 解析纯化-盖盖指令 */
bool AnimationParseHEX::parsingHatPress(QStringList instruct){
    _state_purify->pressHat();
    return true;
}

/** @brief 解析纯化-电机速度指令 */
bool AnimationParseHEX::parsingMotor(QStringList instruct){
    if(instruct.size() < 19){
        return false;
    }

    // 注射器速度 (步数/s)
    double speedStep1 = CommonHelper::Common().SixteenToTen(instruct[7]+instruct[8]).toInt();
    double speedStep2 = CommonHelper::Common().SixteenToTen(instruct[9]+instruct[10]).toInt();
    double speedStep3 = CommonHelper::Common().SixteenToTen(instruct[11]+instruct[12]).toInt();
    double speedStep4 = CommonHelper::Common().SixteenToTen(instruct[13]+instruct[14]).toInt();
    double speedStep5 = CommonHelper::Common().SixteenToTen(instruct[15]+instruct[16]).toInt();
    double speedStep6 = CommonHelper::Common().SixteenToTen(instruct[17]+instruct[18]).toInt();


    double speedMM1 = SyringeCalculator::calStep2MM(1, speedStep1);
    double speedMM2 = SyringeCalculator::calStep2MM(2, speedStep2);
    double speedMM3 = SyringeCalculator::calStep2MM(3, speedStep3);
    double speedMM4 = SyringeCalculator::calStep2MM(4, speedStep4);
    double speedMM5 = SyringeCalculator::calStep2MM(5, speedStep5);
    double speedMM6 = SyringeCalculator::calStep2MM(6, speedStep6);

    _state_purify->changeSyringeSpeedRealTime(1, speedMM1);
    _state_purify->changeSyringeSpeedRealTime(2, speedMM2);
    _state_purify->changeSyringeSpeedRealTime(3, speedMM3);
    _state_purify->changeSyringeSpeedRealTime(4, speedMM4);
    _state_purify->changeSyringeSpeedRealTime(5, speedMM5);
    _state_purify->changeSyringeSpeedRealTime(6, speedMM6);

    return true;
}

/** @brief 解析纯化往废液瓶打的蠕动泵 */
bool AnimationParseHEX::parsingPeristalticPump_Purify(QStringList instruct){
    if(instruct.size() < 10){
        return false;
    }
    if(instruct[8].toInt() == 1){
        _state_purify->changePPumpState(1);
    }else if(instruct[8].toInt() == 0){
        _state_purify->changePPumpState(-1);
    }else{
        _state_purify->changePPumpState(0);
    }
    return true;
}

/** @brief 解析转靶里面的蠕动泵 */
bool AnimationParseHEX::parsingPeristalticPump_Shifting(QStringList instruct){

    if(instruct.size() < 10){
        return false;
    }
    if(instruct[8].toInt() == 1){
        _state_shifting->setPPumpState(1);
    }else if(instruct[8].toInt() == 0){
        _state_shifting->setPPumpState(-1);
    }else{
        _state_shifting->setPPumpState(0);
    }


    return true;
}

/** @brief 解析加热 */
bool AnimationParseHEX::parsingHeating(QStringList instruct){

    if(instruct.size() < 10){
        return false;
    }
    _state_purify->changeHeating(true);

}

/** @brief 解析挡板 */
bool AnimationParseHEX::parsingBaffle(QStringList instruct){

    if(instruct.size() < 10){
        __LOG_ERROR("InstructLengthError: " + instruct.join(" "));
        return false;
    }
    if(instruct[8].toInt() == 1){
        _state_shifting->setBaffleState(1);
    }else{
        _state_shifting->setBaffleState(0);
    }
    return true;
}


/** @brief 解析挡板转靶模块-吸盘-取靶和放靶 */
bool AnimationParseHEX::parsingOpTarget_Practice(QStringList instruct){

    if(instruct.size() < 10){
        __LOG_ERROR("InstructLengthError: " + instruct.join(" "));
        return false;
    }
    if(instruct[8].toInt() == 0 || instruct[8].toInt() == 2){       // 取靶或者检测
        _state_shifting->takeTarget();
    }else if(instruct[8].toInt() == 1){          // 放靶
        _state_shifting->placeTarget();
    }else if(instruct[8].toInt() == 0){
        _state_shifting->moveToRadio();
    }
    return true;
}
/** @brief 解析转靶模块开盖和盖盖29 */
bool AnimationParseHEX::parsingOpCap_Mov(QStringList instruct){

    if(instruct.size() < 10){
        __LOG_ERROR("InstructLengthError: " + instruct.join(" "));
        return false;
    }
    if(instruct[8].toInt() == 0){           // 开盖
        _state_shifting->openCap();
    }else if(instruct[8].toInt() == 1){     // 关盖
        _state_shifting->closeCap();
    }else if(instruct[8].toInt() == 2){     // 移动到靶材罐位置
        _state_shifting->step_move2cap();
        _state_shifting->step_capDown();
    }else if(instruct[8].toInt() == 3){     // 运动到初始位置
        _state_shifting->step_move2origin();
    }else if(instruct[8].toInt() == 4){          // 开盖
        _state_shifting->openCap();
    }else if(instruct[8].toInt() == 5){          // 关盖
        _state_shifting->closeCap();
    }
    return true;
}/** @brief 解析转靶模块开盖和盖盖30 */
bool AnimationParseHEX::parsingOpCap_Clamp(QStringList instruct){

    if(instruct.size() < 10){
        __LOG_ERROR("InstructLengthError: " + instruct.join(" "));
        return false;
    }
    // 移动到靶材罐位置
    if(instruct[9].toInt() == 2){
        _state_shifting->step_move2cap();
    }
    // 移动到初始位置
    else if(instruct[9].toInt() == 3){
        _state_shifting->step_move2origin();
    }

    // 夹紧
    if(instruct[8].toInt() == 0){
        _state_shifting->step_closeCapClamp();
    }
    // 松开
    if(instruct[8].toInt() == 1){
        _state_shifting->step_openCapClamp();
    }

//    if(instruct[8].toInt() == 0){

//    }else if(instruct[8].toInt() == 1){     // 关盖流程
//        _state_shifting->closeCap();
//    }else if(instruct[8].toInt() == 2){     // 移动到靶材罐位置
//        _state_shifting->step_move2cap();
//    }else if(instruct[8].toInt() == 3){     // 运动到初始位置
//        _state_shifting->step_move2origin();
//    }else if(instruct[8].toInt() == 4){

//    }
    return true;
}
/** @brief 解析夹爪 */
bool AnimationParseHEX::parsingClamp(QStringList instruct){

    if(instruct.size() < 10){
        __LOG_ERROR("InstructLengthError: " + instruct.join(" "));
        return false;
    }
    if(instruct[8].toInt() == 0){
        _state_shifting->setClampState(1);
    }else{
        _state_shifting->setClampState(0);
    }
    return true;
}

/** @brief 解析水泵 (冷却) */
bool AnimationParseHEX::parsingWaterPump(QStringList instruct){

    if(instruct.size() < 10){
        __LOG_ERROR("InstructLengthError: " + instruct.join(" "));
        return false;
    }
    if(instruct[8].toInt() == 0){           // 下位机指令0开启1关闭
        _state_practice->setPump1State(1);  // 动画指令0关闭1开启…………
//        if(instruct[9].toInt() == 0){       // 氦气开关 0使用 1不使用
//            _state_practice->setPumpN2State(1);
//        }
    }else{
        _state_practice->setPump1State(0);
//        if(instruct[9].toInt() == 0){       // 氦气开关 0使用 1不使用
//            _state_practice->setPumpN2State(0);
//        }
    }

    if(instruct[9].toInt() == 0){
        _state_practice->setPumpN2State(1);
    }else{
        _state_practice->setPumpN2State(0);
    }

    return true;
}

/** @brief 解析气泵 (干燥) */
bool AnimationParseHEX::parsingAirPump(QStringList instruct){

    if(instruct.size() < 10){
        __LOG_ERROR("InstructLengthError: " + instruct.join(" "));
        return false;
    }
//    if(instruct[8].toInt() == 0){
        _state_practice->setPump2State(1);
//    }else{
//        _state_practice->setPump2State(0);
//    }
    return true;
}

/** @brief 解析加速模块进料口上移和下移 */
bool AnimationParseHEX::parsingMoveFeedPort_Practice(QStringList instruct){

    if(instruct.size() < 10){
        __LOG_ERROR("InstructLengthError: " + instruct.join(" "));
        return false;
    }
    if(instruct[8].toInt() == 0){
        _state_practice->moveFeedPort(0);
    }else{
        _state_practice->moveFeedPort(1);
    }
    return true;
}

/** @brief 吸靶 */
bool AnimationParseHEX::parsingAbsorb_Practice(QStringList instruct){

    if(instruct.size() < 10){
        __LOG_ERROR("InstructLengthError: " + instruct.join(" "));
        return false;
    }

    if(instruct[8].toInt() == 0){
        _state_practice->setAbsorbState(1);
    }else{
        _state_practice->setAbsorbState(0);
    }

    return true;

}

/** @brief 解析移靶和送靶 */
bool AnimationParseHEX::parsingMoveTarget_Practice(QStringList instruct){

    if(instruct.size() < 10){
        __LOG_ERROR("InstructLengthError: " + instruct.join(" "));
        return false;
    }
    if(instruct[8].toInt() == 0){           // 00接靶
        _state_practice->moveBar(1);
        QTimer::singleShot(1200, [=]{
            _state_practice->turnWheel(1);
        });
    }else{                                  // 01送靶
        _state_practice->turnWheel(0);
        QTimer::singleShot(1200, [=]{
            _state_practice->moveBar(0);
        });
    }
    return true;
}
/** @brief 解析抱闸锁定 */
bool AnimationParseHEX::parsingBrake(QStringList instruct){

    if(instruct.size() < 10){
        __LOG_ERROR("InstructLengthError: " + instruct.join(" "));
        return false;
    }
    if(instruct[8].toInt() == 0){
        _state_practice->setBrakeState(1);
    }else{
        _state_practice->setBrakeState(0);
    }
    return true;
}




